home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / qed / src / ausgabe.c < prev    next >
C/C++ Source or Header  |  1998-10-01  |  21KB  |  926 lines

  1. #include <support.h>
  2.  
  3. #include "global.h"
  4. #include "ausgabe.h"
  5. #include "memory.h"
  6. #include "options.h"
  7. #include "rsc.h"
  8. #include "window.h"
  9.  
  10. #define BLKANF        1
  11. #define BLKEND        2
  12. #define BLKFULL    4
  13.  
  14. /* lokale Variablen ********************************************************/
  15. static char    *text = NULL;
  16. static int    text_len = 0;
  17. #define MIN_TEXT_LEN    ((MAX_LINE_LEN+1) / 4)    /* Startlänge: 256 Bytes */
  18.  
  19. /*!! Muessen am Anfang jeder Routine gesetzt werden !!*/
  20. static bool    tab;
  21. static int    tab_size;
  22. static bool    umbrechen;
  23. static bool    show_end;
  24.  
  25.  
  26. /*
  27.  * Dynamischer Zeilenpuffer für die expandierte Zeile. MAX_LINE_LEN reicht
  28.  * nicht aus, wenn eine Zeile echte TABs enthält!
  29.  * Der angeforderte Puffer wird von line_to_str() benutzt.
  30. */
  31. static void adjust_text(TEXTP t_ptr)
  32. {
  33.     int    need;
  34.     
  35.     if (t_ptr->max_line == NULL)
  36.         need = -1;
  37.     else
  38.         need = t_ptr->max_line->exp_len;
  39.     if (text == NULL || need > text_len)
  40.     {
  41.         text_len = max(need, MIN_TEXT_LEN);
  42.         text = realloc(text, text_len + 1);
  43.     }
  44. }
  45.  
  46. /*
  47.  * Expandiert eine ganze Zeile zu einem String für die 
  48.  * Ausgabe mit v_gtext().
  49.  * Tab-Zeichen werden ggf. in mehrere CHR(32) gewandelt
  50.  * Die Stringlänge wird zurückgegeben.
  51. */
  52. static int line_to_str(ZEILEP a, int anz)
  53. {
  54.     int    len, i, end;
  55.     char    *str, c, *t;
  56.  
  57.     t = text;
  58.     str = TEXT(a);
  59.     if (anz == -1)
  60.         end = a->len;
  61.     else
  62.         end = anz;
  63.     if (tab)
  64.     {
  65.         int    tabH;
  66.  
  67.         tabH = tab_size;
  68.         for (i = end, len = text_len; (--i)>=0; )
  69.         {
  70.             c = *str++;
  71.             if (c == '\t')
  72.             {
  73.                 len -= tabH;
  74.                 if (len < 0)
  75.                 {
  76.                     tabH += len;
  77.                     len = 0;
  78.                 }
  79.                 while (TRUE)
  80.                 {
  81.                     *t++ = ' ';    
  82.                     if ((--tabH) == 0) 
  83.                         break;
  84.                 }
  85.                 if (len == 0) 
  86.                     break;            /* Puffer voll */
  87.                 tabH = tab_size;
  88.             }
  89.             else if (c < min_ascii || c > max_ascii)
  90.             {
  91.                 *t++ = ' ';
  92.                 if ((--tabH) == 0) 
  93.                     tabH = tab_size;
  94.                 if ((--len) == 0) 
  95.                     break;        /* Puffer voll */
  96.             }
  97.             else
  98.             {
  99.                 *t++ = c;
  100.                 if ((--tabH) == 0)
  101.                     tabH = tab_size;
  102.                 if ((--len) == 0) 
  103.                     break;        /* Puffer voll */
  104.             }
  105.         }
  106.         len = text_len - len;
  107.         *t = EOS;
  108.     }
  109.     else
  110.     {
  111.         for (i = end, len = 0; (--i) >= 0 && (len < text_len); len++)
  112.         {
  113.             c = *str++;
  114.             if (c < min_ascii || c > max_ascii)
  115.                 *t++ = ' ';
  116.             else
  117.                 *t++ = c;
  118.         }
  119.         *t = EOS;
  120.     }
  121.     return(len);
  122. }
  123.  
  124. /* Liefert die interne Position */
  125. int inter_pos(int x, ZEILEP a, bool tab, int tab_size)
  126. {
  127.     int    len  = 0,
  128.             tabH = tab_size,
  129.              i    = 0;
  130.     char *str;
  131.  
  132.     if (!tab)
  133.         return min(x,a->len);
  134.     str = TEXT(a);
  135.     while(len < x && i < a->len)
  136.     {
  137.         if ((*str++) == '\t')
  138.         {
  139.             len += tabH;
  140.             tabH = tab_size;
  141.         }
  142.         else
  143.         {
  144.             len++;
  145.             if ((--tabH)==0)
  146.                 tabH = tab_size;
  147.         }
  148.         i++;
  149.     }
  150.     if (len > x)
  151.         i--;
  152.     return i;
  153. }
  154.  
  155. int bild_len(ZEILEP a, bool tab, int tab_size)
  156. {
  157.     return bild_pos(a->len,a,tab,tab_size);
  158. }
  159.  
  160. int bild_pos(int x, ZEILEP a, bool tab, int tab_size)
  161. {
  162.     int    len  = 0,
  163.             tabH = tab_size;
  164.     char    *str;
  165.  
  166.     if (!tab)
  167.         return min(x, a->len);
  168.     str = TEXT(a);
  169.     while ((--x)>=0)
  170.     {
  171.         if ((*str++) == '\t')
  172.         {
  173.             len += tabH;
  174.             tabH = tab_size;
  175.         }
  176.         else
  177.         {
  178.             len++;
  179.             if ((--tabH)==0)
  180.                 tabH = tab_size;
  181.         }
  182.     }
  183.     return len;
  184. }
  185.  
  186. /*----------------------------------------------------------------------------
  187.  * Cursor-Handling
  188. */
  189. int cursor_xpos(TEXTP t_ptr, int pos)
  190. {
  191.     int    len;
  192.     
  193.     if (font_prop)
  194.     {
  195.         int    pxy[8];
  196.         
  197.         tab = t_ptr->loc_opt->tab;
  198.         tab_size = t_ptr->loc_opt->tabsize;
  199.         adjust_text(t_ptr);
  200.         line_to_str(t_ptr->cursor_line, pos);
  201.         vqt_extent(vdi_handle, text, pxy);
  202.         len = pxy[2] - pxy[0];
  203.     }
  204.     else
  205.         len = bild_pos(pos, t_ptr->cursor_line, t_ptr->loc_opt->tab, t_ptr->loc_opt->tabsize) * font_wcell;
  206.  
  207.     return len;
  208. }
  209.  
  210. static void _cursor(GRECT *r)
  211. {
  212.     int     pxy[4];
  213.  
  214.     vswr_mode(vdi_handle, MD_XOR);
  215.     if (fill_color != fg_color)
  216.     {
  217.         vsf_color(vdi_handle, fg_color);
  218.         fill_color = fg_color;
  219.     }
  220.     pxy[0] = r->g_x;
  221.     pxy[1] = r->g_y;
  222.     pxy[2] = r->g_x + r->g_w - 1;
  223.     pxy[3] = r->g_y + r->g_h - 1;
  224.     vr_recfl (vdi_handle, pxy);
  225.     vswr_mode(vdi_handle, MD_TRANS);
  226. }
  227.  
  228. void cursor(WINDOWP w, TEXTP t_ptr)
  229. {
  230.     int        pxy[8];
  231.     char        c[2];
  232.     GRECT        curs_rect, clip;
  233.     long        zeile;
  234.     bool        hidden;
  235.  
  236.     /* Position ermitteln */    
  237.     curs_rect.g_x = cursor_xpos(t_ptr, t_ptr->xpos) - ((int) w->doc.x * font_wcell) + w->work.g_x;
  238.  
  239.     zeile = t_ptr->ypos - w->doc.y;
  240.     curs_rect.g_y = (int) zeile * font_hcell + w->work.g_y;
  241.  
  242.     /* Cursor überhaupt sichtbar? */
  243.     if (curs_rect.g_x < w->work.g_x || curs_rect.g_x > (w->work.g_x + w->work.g_w - 1) ||
  244.          curs_rect.g_y < w->work.g_y || curs_rect.g_y > (w->work.g_y + w->work.g_h - 1) ||
  245.          (w->flags & WI_ICONIFIED))
  246.         return;
  247.  
  248.     /* Breite und Höhe ermitteln */    
  249.     if (overwrite)
  250.     {
  251.         if (font_prop)
  252.         {
  253.             c[0] = TEXT(t_ptr->cursor_line)[t_ptr->xpos];
  254.             c[1] = EOS;
  255.             vqt_extent(vdi_handle, c, pxy);
  256.             curs_rect.g_w = pxy[2] - pxy[0];
  257.             if (curs_rect.g_w == 0)
  258.                 curs_rect.g_w = 1;
  259.             curs_rect.g_h = pxy[7] - pxy[1];
  260.         }
  261.         else
  262.         {
  263.             curs_rect.g_w = font_wcell;
  264.             curs_rect.g_h = font_hcell;
  265.         }
  266.     }
  267.     else
  268.     {
  269.         curs_rect.g_w = 3;
  270.         curs_rect.g_h = font_hcell;
  271.     }
  272.  
  273.     /*
  274.      * Am Rand (oben/unten) darf der Cursor nicht überstehen, ansonsten
  275.      * 2 Pixel oben/unten.
  276.      */
  277.     if (zeile > 0)
  278.     {
  279.         curs_rect.g_y -= 2;
  280.         curs_rect.g_h += 2;
  281.     }
  282.     if (zeile < w->w_height-1)
  283.         curs_rect.g_h += 2;
  284.  
  285.     wind_update(BEG_UPDATE);
  286.     hidden = hide_mouse_if_needed(&curs_rect);
  287.  
  288.     if (rc_first(w->handle, &curs_rect, &clip))
  289.     {
  290.         do
  291.         {
  292.             set_clip(TRUE, &clip);
  293.             _cursor(&curs_rect);
  294.         }
  295.         while(rc_next(w->handle, &clip));
  296.     }
  297.     if (hidden)
  298.         show_mouse();
  299.     wind_update(END_UPDATE);
  300. }
  301.  
  302. static ZEILEP get_wline(TEXTP t_ptr, long y)
  303. {
  304.     ZEILEP    lauf;
  305.     long         i;
  306.  
  307.     if (y < 0 || y >= t_ptr->text.lines)
  308.         return NULL;
  309.     i = t_ptr->ypos;
  310.     lauf = t_ptr->cursor_line;
  311.     if (i > y)
  312.     {
  313.         i -= y;
  314.         while (TRUE)
  315.         {
  316.             VORG(lauf);
  317.             if ((--i)==0)
  318.                 break;
  319.         }
  320.     }
  321.     else if (i < y)
  322.     {
  323.         y -= i;
  324.         while (TRUE)
  325.         {
  326.             NEXT(lauf);
  327.             if ((--y)==0)
  328.                 break;
  329.         }
  330.     }
  331.     return (lauf);
  332. }
  333.  
  334. /*-----------------------------------------------------------------------------
  335.  * Fläche füllen.
  336.  *
  337.  * x ist Pixel-Koordinate
  338.  * y ist Pixel-Koordinate
  339.  * w ist die Breite in Pixel, die abgedeckt werden soll
  340. */
  341. void fill_line(int x, int y, int w, int color)
  342. {
  343.     int    pxy[4];
  344.  
  345.     if (w <= 0) 
  346.         return;
  347.     pxy[0] = x;
  348.     pxy[1] = y;
  349.     pxy[2] = w + x - 1;
  350.     pxy[3] = y + font_hcell - 1;
  351.     if (fill_color != color)
  352.     {
  353.         vsf_color(vdi_handle, color);
  354.         fill_color = color;
  355.     }
  356.     vswr_mode(vdi_handle, MD_REPLACE);
  357.     vr_recfl (vdi_handle, pxy);
  358. }
  359.  
  360. /*
  361.  * String mit v_gtext() ausgeben.
  362.  *
  363.  * x ist Pixel-Koordinate
  364.  * y ist Pixel-Koordinate
  365.  * w ist die Breite in Pixel, die abgedeckt werden soll
  366.  * return ende der Textausgabe
  367. */
  368. int out_s(int x, int y, int w, char *str)
  369. {
  370.     int    pxy[8], len;
  371.  
  372.     if (w <= 0)
  373.         return x;
  374.     fill_line(x, y, w, bg_color);
  375.     vswr_mode(vdi_handle, MD_TRANS);
  376.     v_gtext(vdi_handle, x, y, str);
  377.     if (font_prop)
  378.     {
  379.         vqt_extent(vdi_handle, str, pxy);
  380.         len = pxy[2]-pxy[0];
  381.     }
  382.     else
  383.         len = (int) strlen(str) * font_wcell;
  384.  
  385.     if (len < w)
  386.         return x + len;
  387.     return x + w;
  388. }
  389.  
  390. /*
  391.  * String invers mit v_gtext ausgeben.
  392.  *
  393.  * x ist Pixel-Koordinate
  394.  * y ist Pixel-Koordinate
  395.  * w ist die Breite in Pixel, die abgedeckt werden soll
  396.  * return ende der Textausgabe
  397. */
  398. int out_sb(int x, int y, int w, char *str)
  399. {
  400.     int    pxy[8], len;
  401.  
  402.     if (w <= 0)
  403.         return x;
  404.  
  405.     fill_line(x, y, w, fg_color);
  406.     vswr_mode(vdi_handle, MD_XOR);
  407.     v_gtext(vdi_handle, x, y, str);
  408.     if (font_prop)
  409.     {
  410.         vqt_extent(vdi_handle, str, pxy);
  411.         len = pxy[2] - pxy[0];
  412.     }
  413.     else
  414.         len = (int) strlen(str) * font_wcell;
  415.     if (len > w)
  416.         return x + w;
  417.     return x + len;
  418. }
  419.  
  420. /*
  421.  * Absatzmarke zeichnen.
  422. */
  423. static void draw_cr(int x, int y, bool inv)
  424. {
  425.     int pxy[6], h, b;
  426.  
  427.     if (inv)
  428.         vsl_color(vdi_handle, bg_color);
  429.     else
  430.         vsl_color(vdi_handle, fg_color);
  431.     b = min(font_wcell, font_hcell);
  432.     h = b >> 1;
  433.     y += (font_hcell >> 1);
  434.     pxy[0] = x + b - 1;            /* oben rechts */
  435.     pxy[1] = y - h;
  436.     pxy[2] = x + b - 1;            /* mitte rechst */
  437.     pxy[3] = y;
  438.     pxy[4] = x;                        /* mitte links */
  439.     pxy[5] = y;
  440.     v_pline (vdi_handle, 3, pxy);
  441.     h = h >> 1;
  442.     pxy[0] = x + h;                    /* schräg oben */
  443.     pxy[1] = y - h;
  444.     pxy[2] = x;                        /* mitte links */
  445.     pxy[3] = y;
  446.     pxy[4] = x + h;                    /* schräg unten */
  447.     pxy[5] = y + h;
  448.     v_pline (vdi_handle, 3, pxy);
  449.     if (inv)
  450.         vsl_color(vdi_handle, fg_color);
  451.     else
  452.         vsl_color(vdi_handle, bg_color);
  453. }
  454.  
  455. /*
  456.  * String mit v_gtext() ausgeben.
  457.  *
  458.  * x ist Pixel-Koordinate
  459.  * y ist Pixel-Koordinate
  460.  * w ist die Breite in Pixel, die abgedeckt werden soll
  461.  * offset in Zeichen
  462. */
  463. static void str_out(int x, int y, int w, int offset, ZEILEP a)
  464. {
  465.     int    len, anz;
  466.     int    pxy[8];
  467.  
  468.     anz = line_to_str(a, -1);
  469.     fill_line(x, y, w, bg_color);
  470.     vswr_mode(vdi_handle, MD_TRANS);
  471.     if (font_prop)
  472.     {
  473.         /* auf bei prop. wird um font_wcell gescrollt! */
  474.         offset *= font_wcell;
  475.         x -= offset;
  476.         w += offset;
  477.         v_gtext(vdi_handle, x, y, text);
  478.         vqt_extent(vdi_handle, text, pxy);
  479.         len = pxy[2] - pxy[0];
  480.         if (len < w)
  481.         {
  482.             if (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end))
  483.                 draw_cr(x+len, y, FALSE);
  484.         }
  485.     }
  486.     else
  487.     {
  488.         if (offset >= anz)
  489.         {
  490.             /* kein Text, ganze Zeile leer */
  491.             if (offset == anz && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  492.                 draw_cr(x, y, FALSE);
  493.         }
  494.         else
  495.         {
  496.             anz -= offset;
  497.             len = anz * font_wcell;
  498.             if (w <= len)
  499.             {
  500.                 /* Zeile bis zum rechten Fensterrand */
  501.                 text[offset+w/font_wcell] = EOS;
  502.                 v_gtext(vdi_handle, x, y, text+offset);
  503.             }
  504.             else
  505.             {
  506.                 v_gtext(vdi_handle, x, y, text+offset);
  507.                 if (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end))
  508.                     draw_cr(x + len, y, FALSE);
  509.             }
  510.         }
  511.     }
  512. }
  513.  
  514. /*
  515.  * String mit v_gtext() invers ausgeben.
  516.  *
  517.  * x ist Pixel-Koordinate
  518.  * y ist Pixel-Koordinate
  519.  * w ist die Breite in Pixel, die abgedeckt werden soll
  520.  * offset in Zeichen
  521.  * mode (BLKANF, BLKEND, BLKFULL)
  522. */
  523. static void str_out_b(int x, int y, int w, int offset, ZEILEP a, int mode, int x1, int x2)
  524. {
  525.     int    anz, anz1, anz2, len, len2, pxy[8], end;
  526.     char    h;
  527.  
  528.     anz = line_to_str(a, -1);
  529.     if (anz <= offset)        /* ganze Zeile weiss oder schwarz ohne Text */
  530.     {
  531.         if (font_prop)
  532.         {
  533.             vqt_extent(vdi_handle,text,pxy);
  534.             end = x - (offset * font_wcell) + (pxy[2] - pxy[0]);
  535.         }
  536.         else
  537.             end = x - (offset * font_wcell) + anz * font_wcell;
  538.         if (mode == BLKFULL || mode == BLKANF)
  539.         {
  540.             fill_line(x, y, w, fg_color);
  541.             if (end >= x && end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  542.                 draw_cr(end, y, TRUE);
  543.         }
  544.         else
  545.         {
  546.             fill_line(x, y, w, bg_color);
  547.             if (end >= x && end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  548.                 draw_cr(end, y, FALSE);
  549.         }
  550.         return;
  551.     }
  552.     if (font_prop)
  553.     {
  554.         offset *= font_wcell;
  555.         x -= offset;
  556.         w += offset;
  557.         if (mode==BLKFULL)
  558.         /* Ganze Zeile einheitlich invers */
  559.         {
  560.             end = out_sb(x,y,w,text);
  561.             if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  562.                 draw_cr(end, y, TRUE);
  563.         }
  564.         else
  565.         /* Blockanfang oder -ende oder beides */
  566.         {
  567.             if (mode==BLKANF)
  568.             {
  569.                 anz1 = bild_pos(x1,a,tab,tab_size);
  570.                 h = text[anz1]; text[anz1] = EOS;
  571.                 vqt_extent(vdi_handle,text,pxy);
  572.                 len = pxy[2]-pxy[0];
  573.                 end = out_s(x,y,len,text);
  574.                 text[anz1] = h;
  575.                 end = out_sb(end,y,w-len,text+anz1);
  576.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  577.                     draw_cr(end, y, TRUE);
  578.             }
  579.             else if (mode==BLKEND)
  580.             {
  581.                 anz1 = bild_pos(x2,a,tab,tab_size);
  582.                 h = text[anz1]; text[anz1] = EOS;
  583.                 vqt_extent(vdi_handle,text,pxy);
  584.                 len = pxy[2]-pxy[0];
  585.                 end = out_sb(x,y,len,text);
  586.                 text[anz1] = h;
  587.                 end = out_s(end,y,w-len,text+anz1);
  588.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  589.                     draw_cr(end, y, FALSE);
  590.             }
  591.             else /* (mode==(BLKANF+BLKEND) */
  592.             {
  593.                 anz1 = bild_pos(x1,a,tab,tab_size);
  594.                 h = text[anz1]; text[anz1] = EOS;
  595.                 vqt_extent(vdi_handle,text,pxy);
  596.                 len = pxy[2]-pxy[0];
  597.                 end = out_s(x,y,len,text);
  598.                 text[anz1] = h;
  599.  
  600.                 anz2 = bild_pos(x2,a,tab,tab_size);
  601.                 h = text[anz2]; text[anz2] = EOS;
  602.                 vqt_extent(vdi_handle,text+anz1,pxy);
  603.                 len2 = pxy[2]-pxy[0];
  604.                 end = out_sb(end,y,len2,text+anz1);
  605.                 text[anz2] = h;
  606.  
  607.                 end = out_s(end,y,w-len-len2,text+anz2);
  608.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  609.                     draw_cr(end, y, FALSE);
  610.             }
  611.         }
  612.     }
  613.     else
  614.     {
  615.         char *ptr = text+offset;
  616.  
  617.         anz -= offset;
  618.         if (anz * font_wcell > w)
  619.         {
  620.             anz = w/font_wcell;
  621.             ptr[anz] = EOS;
  622.         }
  623.         if (mode == BLKFULL)
  624.         /* Ganze Zeile einheitlich invers */
  625.         {
  626.             end = out_sb(x,y,w,ptr);
  627.             if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  628.                 draw_cr(end, y, TRUE);
  629.         }
  630.         else
  631.         /* Blockanfang oder -ende oder beides */
  632.         {
  633.             if (mode==BLKANF)
  634.             {
  635.                 anz1 = bild_pos(x1,a,tab,tab_size)-offset;
  636.                 if (anz1<0) anz1 = 0;
  637.                 if (anz1>anz) anz1 = anz;
  638.                 h = ptr[anz1]; ptr[anz1] = EOS;
  639.                 len = anz1*font_wcell;
  640.                 end = out_s(x,y,len,ptr);
  641.                 ptr[anz1] = h;
  642.                 end = out_sb(end,y,w-len,ptr+anz1);
  643.  
  644.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  645.                     draw_cr(end,y, TRUE);
  646.             }
  647.             else if (mode==BLKEND)
  648.             {
  649.                 anz1 = bild_pos(x2,a,tab,tab_size)-offset;
  650.                 if (anz1<0) anz1 = 0;
  651.                 if (anz1>anz) anz1 = anz;
  652.                 h = ptr[anz1]; ptr[anz1] = EOS;
  653.                 len = anz1*font_wcell;
  654.                 end = out_sb(x,y,len,ptr);
  655.                 ptr[anz1] = h;
  656.                 end = out_s(end,y,w-len,ptr+anz1);
  657.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  658.                     draw_cr(end, y, FALSE);
  659.             }
  660.             else /* (mode==(BLKANF+BLKEND) */
  661.             {
  662.                 anz1 = bild_pos(x1,a,tab,tab_size)-offset;
  663.                 if (anz1<0) anz1 = 0;
  664.                 if (anz1>anz) anz1 = anz;
  665.                 h = ptr[anz1]; ptr[anz1] = EOS;
  666.                 len = anz1*font_wcell;
  667.                 end = out_s(x,y,len,ptr);
  668.                 ptr[anz1] = h;
  669.  
  670.                 anz2 = bild_pos(x2,a,tab,tab_size)-offset;
  671.                 if (anz2<0) anz2 = 0;
  672.                 if (anz2>anz) anz2 = anz;
  673.                 h = ptr[anz2]; ptr[anz2] = EOS;
  674.                 len2  = anz2*font_wcell - len;
  675.                 end = out_sb(end,y,len2,ptr+anz1);
  676.                 ptr[anz2] = h;
  677.  
  678.                 end = out_s(end,y,w-len-len2,ptr+anz2);
  679.                 if (end < x + w && (IS_OVERLEN(a) || (umbrechen && IS_ABSATZ(a) && show_end)))
  680.                     draw_cr(end, y, FALSE);
  681.             }
  682.         }
  683.     }
  684. }
  685.  
  686. /* =========================================================== */
  687.  
  688. void line_out(WINDOWP window, TEXTP t_ptr, int wy)
  689. {
  690.     int        y;
  691.     ZEILEP    col;
  692.  
  693.     adjust_text(t_ptr);                    /* Zeilenpuffer an exp_len anpassen */
  694.     tab = t_ptr->loc_opt->tab;
  695.     tab_size = t_ptr->loc_opt->tabsize;
  696.     umbrechen = t_ptr->loc_opt->umbrechen;
  697.     show_end = t_ptr->loc_opt->show_end;
  698.     y = window->work.g_y+wy*font_hcell;
  699.     col = get_wline(t_ptr, window->doc.y+wy);
  700.     if (col != NULL)                                                /* Kommt vor */
  701.     {
  702.         if (t_ptr->block)
  703.         {
  704.             wy += (int) window->doc.y;
  705.             if (wy<t_ptr->z1 || wy>t_ptr->z2)
  706.                 str_out(window->work.g_x, y, window->work.g_w, (int)window->doc.x, col);
  707.             else
  708.             {
  709.                 int    mode = 0;
  710.  
  711.                 if (wy == t_ptr->z1)
  712.                     mode |= BLKANF;
  713.                 if (wy == t_ptr->z2)
  714.                     mode |= BLKEND;
  715.                 if (!mode)
  716.                     mode = BLKFULL;
  717.                 str_out_b(window->work.g_x, y, window->work.g_w,
  718.                          (int) window->doc.x, col, mode, t_ptr->x1, t_ptr->x2);
  719.             }
  720.         }
  721.         else
  722.             str_out(window->work.g_x, y, window->work.g_w, (int) window->doc.x, col);
  723.     }
  724.     else
  725.         fill_line(window->work.g_x, y, window->work.g_w, bg_color);
  726. }
  727.  
  728. void bild_out(WINDOWP window, TEXTP t_ptr)
  729. {
  730.     int        x, y, w, xy[4];
  731.     ZEILEP    lauf;
  732.     int        min_col, max_col, max_y;
  733.     GRECT        c;
  734.  
  735.     adjust_text(t_ptr);                    /* Zeilenpuffer an exp_len anpassen */
  736.     tab = t_ptr->loc_opt->tab;
  737.     tab_size = t_ptr->loc_opt->tabsize;
  738.     umbrechen = t_ptr->loc_opt->umbrechen;
  739.     show_end = t_ptr->loc_opt->show_end;
  740.     x = window->work.g_x;
  741.     y = window->work.g_y;
  742.     w = window->work.g_w;
  743.  
  744.     if (window->class == CLASS_EDIT)                        /* Kopf ausgeben */
  745.         head_out(window, t_ptr);
  746.  
  747.     min_col = 0;
  748.     max_col = (int) min(window->w_height - 1, t_ptr->text.lines - window->doc.y-1);
  749.     max_y   = y + window->work.g_h-1;
  750.     if (get_clip(&c))                    /* nicht alles malen */
  751.     {
  752.         int y2 = c.g_y - y;
  753.  
  754.         min_col = max(min_col, y2/font_hcell);
  755.         max_col = min(max_col, (c.g_y + c.g_h - 1) / font_hcell);
  756.         max_y = min(max_y, c.g_y + c.g_h - 1);
  757.     }
  758.     y += (min_col * font_hcell);
  759.     lauf = get_wline(t_ptr, window->doc.y + min_col);
  760.     if (lauf != NULL)
  761.     {
  762.         int    xoffset, i;
  763.  
  764.         xoffset = (int) window->doc.x;
  765.         if (t_ptr->block)
  766.         {
  767.             long    y_r;
  768.  
  769.             y_r = window->doc.y+min_col;
  770.             for (i=min_col ; i<=max_col; y_r++,y+=font_hcell,NEXT(lauf),i++)
  771.             {
  772.                 /* Block nicht sichtbar */
  773.                 if (y_r < t_ptr->z1 || y_r > t_ptr->z2)
  774.                     str_out(x, y, w, xoffset, lauf);
  775.                 else
  776.                 {
  777.                     int mode = 0;
  778.  
  779.                     if (y_r == t_ptr->z1)
  780.                         mode |= BLKANF;
  781.                     if (y_r == t_ptr->z2)
  782.                         mode |= BLKEND;
  783.                     if (!mode)
  784.                         mode = BLKFULL;
  785.                     str_out_b(x, y, w, xoffset, lauf, mode, t_ptr->x1, t_ptr->x2);
  786.                 }
  787.             }
  788.         }
  789.         else
  790.         {
  791.             for (i=min_col ; i<=max_col; y+=font_hcell,NEXT(lauf),i++)
  792.                 str_out(x,y,w,xoffset,lauf);
  793.         }
  794.     }
  795.     if (y < max_y)
  796.     {
  797.         xy[0] = x;
  798.         xy[1] = y;
  799.         xy[2] = x + w - 1;
  800.         xy[3] = max_y;
  801.         if (fill_color != bg_color)
  802.         {
  803.             vsf_color(vdi_handle, bg_color);
  804.             fill_color = bg_color;
  805.         }
  806.         vr_recfl(vdi_handle, xy);
  807.     }
  808. }
  809.  
  810. void bild_blkout(WINDOWP window, TEXTP t_ptr, long z1, long z2)
  811. /* Alle Textzeilen zwischen z1 und z2 werden neu ausgegeben */
  812. {
  813.     int    i, x, y, w, xoffset;
  814.     ZEILEP lauf;
  815.     int    MAX_COL;
  816.     long    lines, y_r;
  817.  
  818.     adjust_text(t_ptr);                    /* Zeilenpuffer an exp_len anpassen */
  819.     tab = t_ptr->loc_opt->tab;
  820.     tab_size = t_ptr->loc_opt->tabsize;
  821.     umbrechen = t_ptr->loc_opt->umbrechen;
  822.     show_end = t_ptr->loc_opt->show_end;
  823.     if (z1>z2)
  824.     {
  825.         lines = z1;
  826.         z1 = z2;
  827.         z2 = lines;
  828.     }
  829.     x          = window->work.g_x;
  830.     y           = window->work.g_y;
  831.     w          = window->work.g_w;
  832.     xoffset = (int) window->doc.x;
  833.     MAX_COL = (int) min(window->w_height-1, t_ptr->text.lines-window->doc.y-1);
  834.     y_r      = window->doc.y;
  835.     lauf = get_wline(t_ptr, y_r);
  836.  
  837.     if (t_ptr->block)
  838.         for (i=0; i<=MAX_COL; i++,y+=font_hcell,y_r++)
  839.         {
  840.             if (y_r>=z1 && y_r<=z2)
  841.             {
  842.                 if (y_r<t_ptr->z1 || y_r>t_ptr->z2)
  843.                     str_out(x,y,w,xoffset,lauf);
  844.                 else
  845.                 {
  846.                     int mode = 0;
  847.  
  848.                     if (y_r==t_ptr->z1) mode |= BLKANF;
  849.                     if (y_r==t_ptr->z2) mode |= BLKEND;
  850.                     if (!mode) mode = BLKFULL;
  851.                     str_out_b(x,y,w,xoffset,lauf,mode,t_ptr->x1,t_ptr->x2);
  852.                 }
  853.             }
  854.             NEXT(lauf);
  855.         }
  856.     else
  857.         for (i=0; i<=MAX_COL; i++,y+=font_hcell,y_r++)
  858.         {
  859.             if (y_r>=z1 && y_r<=z2)
  860.                 str_out(x,y,w,xoffset,lauf);
  861.             NEXT(lauf);
  862.         }
  863. }
  864.  
  865.  
  866. /***************************************************************************/
  867.  
  868. void head_out(WINDOWP window, TEXTP t_ptr)
  869. {
  870.     char    head_str[WINSTRLEN];
  871.     int    len, head_len;
  872.  
  873.     if (t_ptr->info_str[0] != EOS)
  874.     {
  875.         strncpy(head_str, t_ptr->info_str, WINSTRLEN);
  876.         head_str[WINSTRLEN] = EOS;
  877.         head_len = (int) strlen(head_str);
  878.     }
  879.     else 
  880.     {
  881.         if (t_ptr->text.ending != binmode)
  882.         {
  883.             head_len = (int) strlen(rsc_string(HEADSTR));
  884.             strcpy(head_str, rsc_string(HEADSTR));
  885.             if (t_ptr->readonly)
  886.                 head_str[1] = '\x7F';
  887.     
  888.             switch (t_ptr->text.ending)
  889.             {
  890.                 case tos :
  891.                     break;
  892.                 case unix :
  893.                     head_str[2] = 'U';
  894.                     break;
  895.                 case apple :
  896.                     head_str[2] = 'A';
  897.                     break;
  898.                 default:
  899.                     head_str[2] = '?';
  900.             }
  901.  
  902.             ltoa(t_ptr->ypos+1, head_str + 8, 10);
  903.             head_str[strlen(head_str)] = ' ';
  904.             itoa(bild_pos(t_ptr->xpos,t_ptr->cursor_line,tab,tab_size)+1,head_str+18,10);
  905.             head_str[strlen(head_str)] = ' ';
  906.         }
  907.         else
  908.         {
  909.             long    p;
  910.             
  911.             head_len = (int) strlen(rsc_string(BHEADSTR));
  912.             strcpy(head_str, rsc_string(BHEADSTR));
  913.             if (t_ptr->readonly)
  914.                 head_str[1] = '\x7F';
  915.             p = t_ptr->ypos * t_ptr->text.max_line_len + t_ptr->xpos + 1;
  916.             ltoa(p, head_str + 24, 10);
  917.         }
  918.     }
  919.     len = window->work.g_w / gl_wchar;
  920.     if (len < head_len)
  921.         head_str[len] = EOS;
  922.     set_winfo(window, head_str);
  923. }
  924.  
  925. /***************************************************************************/
  926.